package org.jugile.jsontmpl.domain;


import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Comparator;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.Set;

import org.apache.log4j.Logger;
import org.jugile.util.*;


import org.jugile.jsontmpl.common.*;

public class Array2Collection extends CollectionBase implements java.lang.Iterable<Array2> {
	static Logger log = Logger.getLogger(Array2Collection.class);
	
	private Bos<Array2> items;
	
	public Array2Collection() {
		items = new Bos<Array2>();
	}
	public Array2Collection(Bos<Array2> lst) {
		if (lst == null) items = new Bos<Array2>();
		else items = lst.clone();
	}
	public Array2Collection(List<Array2> list) {
		items = new Bos<Array2>();		
		items.add(list);
	}
	
	public void add(List<String> ids) {
		if (ids != null) {
			items = new Bos<Array2>();		
			Domain d = Domain.getDomain();
			for (String id : ids) add(d.getArray2(id));
		}		
	}

	public boolean contains(Array2 o) { return items.contains(o);	}
	public void add(Array2 o) { items.add(o);	}
	public void remove(Array2 o) { items.remove(o); }
	public Array2Collection clone() { return new Array2Collection(items.clone()); }
	public int size() { filter(); return items.size(); }
	public Set<Long> getKeys() { return items.getKeys(); }
	
	private Query q = null;
	private Query q() {
		if (q == null) q = new Query();
		return q;
	}
	private void filter() {
		if (q != null) items = items.query(q);
		q = null;
	}
	
	// ---- operations -----
	public Array2Collection and(Array2Collection c) { items.and(c.items); return this; }
	public Array2Collection not(Array2Collection c) { items.not(c.items); return this; }
	public Array2Collection xor(Array2Collection c) { items.xor(c.items); return this; }
	public Array2Collection or(Array2Collection c) { items.or(c.items); return this; }
	public Array2Collection keep(String mname) { items.keep(mname); return this; }
	public Array2Collection not(String mname) { items.not(mname); return this; }


	// ---- attribute finders ----
	public Array2Collection byDesc(String v) { q().and("==", "desc", v); return this; }
	public Array2Collection byDesc(String op, String v) { q().and(op, "desc", v); return this; }
	public Array2Collection byCall(String v) { q().and("==", "call", v); return this; }
	public Array2Collection byCall(String op, String v) { q().and(op, "call", v); return this; }
 

	// ---- filtering finders ----
 

	// ---- utility services ----
	public Bos<Array2> getItems() { filter(); return items; }
	public List<Array2> list() { filter();	return items.sort("id"); }
	public Iterator<Array2> iterator() { filter();	return items.iterator(); }

	
 
	// --- n - 1 ----
 

	public List<Array2> page(int page, int size, String sortcriteria) {
		filter();
		return items.page(page, size, sortcriteria);
	}

	public List<Array2> sublist(int start, int end, String sortcriteria) {
		filter();
		return items.sublist(start, end, sortcriteria);
	}

	
	public List<Array2> sort(String fld) { filter(); return items.sort(fld); }
	public Array2 next() { filter(); return iterator().next(); }
	public boolean hasNext() { filter(); return iterator().hasNext(); }
	public Array2 unique() { 
		Query q2 = q;
		if (size() > 1) {
			String querystr = "";
			try {
				if (q2 != null) querystr = q2.toString();
			} catch (Exception e) {}
			//Jugile.fail("Not unique Array2 : " + size() + " q: "+querystr);
			log.error("Not unique Array2 : " + size() + " q: "+querystr);
			return first("id");
		}
		if(!hasNext()) return null; 
		return next(); 
	}
	
	public List<Array2> first(int count) { return first(count,"id");} 
	public List<Array2> first(int count, String sort) {
		List<Array2> res = sort(sort);
		if (count > res.size()) count = res.size();
		return res.subList(0, count);
	}
	public Array2 first(String sort) { 
		List<Array2> res = first(1,sort);
		if (res.size() > 0) return res.get(0);
		return null;
	}
	
	public void add(Array2Collection c) {
		items.add(c.items);
	}
	


}